Skip to content

feat(p2p): add tx validation for contract class id verification#21788

Merged
spalladino merged 1 commit intomerge-train/spartanfrom
palla/contract-class-id-validator
Mar 20, 2026
Merged

feat(p2p): add tx validation for contract class id verification#21788
spalladino merged 1 commit intomerge-train/spartanfrom
palla/contract-class-id-validator

Conversation

@spalladino
Copy link
Contributor

@spalladino spalladino commented Mar 19, 2026

Motivation

Contract class registration events contain a class ID alongside the fields needed to recompute it (artifactHash, privateFunctionsRoot, packed bytecode). This adds a validation to avoid a malicious tx from registering a class with a mismatched ID if it found a bug in the registry contract, poisoning the archiver's contract data.

Approach

Made toContractClassPublic() a simple synchronous conversion with no validation (symmetric with how toContractInstance() works for contract instances). Validation is done explicitly at each call site that needs it: the DataTxValidator and the archiver's updatePublishedContractClasses.

Changes

  • protocol-contracts: toContractClassPublic() is now sync and returns ContractClassPublic without validation or bytecode commitment; toContractClassPublicWithBytecodeCommitment() adds the commitment but also does not validate
  • stdlib: Added TX_ERROR_INCORRECT_CONTRACT_CLASS_ID and TX_ERROR_MALFORMED_CONTRACT_CLASS_LOG error constants; added elapsed timing test for computeContractClassId with real artifacts
  • p2p: Extended DataTxValidator with explicit contract class ID verification (recomputes class ID from event fields and compares)
  • p2p (tests): Added contract class ID validation tests to data_validator.test.ts; updated factory tests
  • archiver: updatePublishedContractClasses explicitly validates class IDs and collects bytecode commitments in a single pass; addContractClasses now takes ContractClassPublicWithCommitment[] instead of separate arrays
  • simulator: Simplified addContractClassesFromEvents and callers from async to sync since toContractClassPublic() is no longer async

@spalladino spalladino force-pushed the palla/contract-class-id-validator branch 3 times, most recently from 3f033bb to bb1a500 Compare March 19, 2026 14:13
@spalladino spalladino force-pushed the palla/contract-class-id-validator branch from bb1a500 to f4d378b Compare March 19, 2026 15:17
@spalladino spalladino enabled auto-merge (squash) March 19, 2026 15:19
@spalladino spalladino force-pushed the palla/contract-class-id-validator branch 3 times, most recently from ae083d0 to 08d4485 Compare March 20, 2026 12:22
@spalladino spalladino changed the title feat(p2p): add tx validator for contract class id verification feat(p2p): add tx validation for contract class id verification Mar 20, 2026
@spalladino spalladino force-pushed the palla/contract-class-id-validator branch from 08d4485 to d045566 Compare March 20, 2026 14:10
Validates that contract class registration logs contain correct class IDs
by recomputing from the event fields (artifactHash, privateFunctionsRoot,
bytecodeCommitment). Also adds defense-in-depth validation in the archiver
and eliminates a redundant bytecodeCommitment computation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@spalladino spalladino force-pushed the palla/contract-class-id-validator branch from d045566 to f86652a Compare March 20, 2026 15:02
@spalladino spalladino merged commit c3c6230 into merge-train/spartan Mar 20, 2026
11 checks passed
@spalladino spalladino deleted the palla/contract-class-id-validator branch March 20, 2026 15:20
@AztecBot
Copy link
Collaborator

❌ Failed to cherry-pick to v4-next due to conflicts. (🤖) View backport run.

AztecBot pushed a commit that referenced this pull request Mar 20, 2026
AztecBot pushed a commit that referenced this pull request Mar 20, 2026
spalladino added a commit that referenced this pull request Mar 20, 2026
…class id verification) to v4-next (#21852)

## Summary
Backport of #21788
to v4-next.

Adds contract class ID validation to the `DataTxValidator` and
archiver's `updatePublishedContractClasses`, preventing malicious txs
from registering classes with mismatched IDs. Also simplifies
`toContractClassPublic()` to be synchronous with explicit validation at
call sites.

## Conflicts Resolved
Cherry-pick had 7 conflict regions across 5 files. Key differences on
v4-next:
- `ContractClassPublic` type includes
`privateFunctions`/`utilityFunctions` arrays (not present on next)
- Different import paths for `DataStoreConfig` and `L1RollupConstants`
- Different test expectations for duplicate contract class registration

Full conflict resolution analysis:
https://gist.github.com/AztecBot/7bae9da9cdc612e1df373324a58e6b24

## Test plan
- TypeScript compilation passes for all modified packages
- Existing tests should pass (test structure adapted for v4-next)
- CI will validate end-to-end"

ClaudeBox log: https://claudebox.work/s/4066b8ad44d62582?run=1

---------

Co-authored-by: Santiago Palladino <santiago@aztecprotocol.com>
github-merge-queue bot pushed a commit that referenced this pull request Mar 20, 2026
BEGIN_COMMIT_OVERRIDE
feat(p2p): add tx validator for contract instance deployment addresses
(#21771)
fix: always deploy IRM for testnet (#21755)
fix: avoid mutating caller's array via splice in snapshot sync (A-718)
(#21759)
chore: update network logs skill (#21785)
feat(archiver): validate contract instance addresses before storing
(#21787)
fix: ensure no division by 0 (#21786)
feat: support private fork releases via ci-release (#21778)
fix: restrict scenario deployments to only nightly (#21798)
fix(stdlib): zero-pad bufferFromFields when declared length exceeds
payload (#21802)
test(protocol-contracts): verify max-size bytecode fits in contract
class log (#21818)
fix: wire BOT_DA_GAS_LIMIT through helm/terraform for staging-public
(#21809)
fix: remove jest-mock-extended from worker processes + fix
parallelize_strict silent failures (#21821)
fix(archiver): throw on duplicate contract class or instance additions
(#21799)
chore: remove broadcasted function events (#21805)
fix: sync dateProvider from anvil stdout on every mined block (#21829)
fix(sequencer): use wall-clock time instead of L1 block timestamp for
slot estimation (#21769)
fix: use correct EthCheatCodes method name in epochs_missed_l1_slot test
(#21848)
feat(p2p): add tx validator for contract class id verification (#21788)
feat: publisher funding (#21631)
feat: batch chonk verifier TS integration (#21823)
fix(sequencer): remove l1 block timestamp check (#21853)
fix: use local IVC inputs for batch_verifier bench test (#21857)
fix(p2p): centralize gossipsub penalization and fix inconsistencies
(#21863)
chore: publish GitHub releases to AztecProtocol/barretenberg (#21775)
END_COMMIT_OVERRIDE
AztecBot added a commit that referenced this pull request Mar 21, 2026
BEGIN_COMMIT_OVERRIDE
chore: backport #21754 (feat!: make isContractInitialized a tri-state
enum) to v4-next (#21792)
fix(stdlib): zero-pad bufferFromFields when declared length exceeds
payload (#21802)
test(protocol-contracts): verify max-size bytecode fits in contract
class log (#21818)
chore: port P2P mesh topic deflake fix to v4-next (#21825)
fix(archiver): throw on duplicate contract class or instance additions
(#21799)
feat: sync poseidon in the browser (#21833)
chore: backport #21824 (fix(aztec-up): add sensible defaults to
installer y/n prompts) to v4-next (#21844)
fix(sequencer): backport wall-clock time for slot estimation to v4-next
(#21769) (#21847)
chore: backport PR #21788 (feat(p2p): add tx validation for contract
class id verification) to v4-next (#21852)
feat: sync poseidon browser (#21851)
END_COMMIT_OVERRIDE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants